﻿using PARK.Common.Core.Manager;
using PARK.Common.Enum;
using PARK.Common.Extension;
using PARK.Common.Filter;
using PARK.Dependency;
using PARK.DynamicApiController;
using PARK.FriendlyException;
using Mapster;
using Microsoft.AspNetCore.Mvc;
using SqlSugar;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Yitter.IdGenerator;
using PARK.Common.Helper;
using PARK.JsonSerialization;
using PARK.Accessctl.Interfaces.AccessCtlauth;
using PARK.Accessctl.Entitys;
using PARK.Accessctl.Entitys.Dto.AccessCtlauth;
using PARK.System.Entitys.Permission;
using PARK.Common.Util.SM4;
using PARK.System.Interfaces.Permission;
using PARK.Common.Util;
using System.Text;
using PARK.CardAcct.Entitys;
using PARK.Accessctl.Entitys.Dto.Wechat;

namespace PARK.Accessctl.AccessCtlauth
{
    /// <summary>
    /// 门禁权限服务
    /// </summary>
    [ApiDescriptionSettings(Tag = "Wechat", Name = "AccessAuth", Order = 200)]
    [Route("api/wechat/[controller]")]
    public class AccessAuthService : IAccessAuthService, IDynamicApiController, ITransient
    {
        private readonly ISqlSugarRepository<AccessCtlauthEntity> _accessCtlauthRepository;
        private readonly SqlSugarScope _db;
        private readonly IUserManager _userManager;
        private readonly IOrganizeService _organizeService; // 机构表仓储

        /// <summary>
        /// 初始化一个<see cref="AccessAuthService"/>类型的新实例
        /// </summary>
        public AccessAuthService(
            ISqlSugarRepository<AccessCtlauthEntity> accessCtlauthRepository,
            IUserManager userManager,
            IOrganizeService organizeService)
        {
            _accessCtlauthRepository = accessCtlauthRepository;
            _db = _accessCtlauthRepository.Context;
            _userManager = userManager;
            _organizeService = organizeService;
        }

        #region 小程序端
        /// <summary>
        /// 获取门禁二维码
        /// </summary>
        /// <returns></returns>
        [HttpGet("GetAccessQR")]
        public async Task<dynamic> GetAccessQR()
        {
            try
            {
                var userInfo = await _userManager.GetUserInfo();
                if (userInfo != null && userInfo.UserKind == 1 && !string.IsNullOrEmpty(userInfo.EmployeeId))
                {
                    var _EmployeeEntity = await _db.Queryable<EmployeeEntity>().FirstAsync(p => p.EmployeeId == userInfo.EmployeeId);
                    if (_EmployeeEntity != null)
                    {
                        if(_EmployeeEntity.AccStatus==1)
                        {
                            var _CardNo = _EmployeeEntity.CardNo;
                            var _QRPassword = PARK.App.Configuration["AccessSettings:QRPassword"]; //"0123456789ABCDEF"; 
                            var _EffeDuration = PARK.App.Configuration["AccessSettings:EffeDuration"]; //有效时长(秒)
                            byte[] sendData = { (byte)0, (byte)0, (byte)0, (byte)0, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0, (byte)0, (byte)0, (byte)0, (byte)0, (byte)0, (byte)0x00, (byte)0x00 };
                            sendData[15] = 2; //固定
                            //起始日期时间
                            DateTime ptm = DateTime.Now;
                            long ymd = getYMD(ptm.Year, ptm.Month, ptm.Day);
                            long hms = getHMS(ptm.Hour, ptm.Minute, ptm.Second);
                            sendData[8] = (byte)(ymd & 0xff);
                            sendData[9] = (byte)((ymd >> 8) & 0xff);
                            sendData[10] = (byte)((hms >> 8) & 0xff); //高位
                            sendData[11] = (byte)(hms & 0xE0); //低位
                            //截止日期时间
                            ptm = DateTime.Now.AddSeconds(int.Parse(_EffeDuration));
                            var _EndDatetime = ptm;
                            ymd = getYMD(ptm.Year, ptm.Month, ptm.Day);
                            hms = getHMS(ptm.Hour, ptm.Minute, ptm.Second);
                            sendData[11] = (byte)(sendData[11] + ((hms & 0xE0) >> 4));
                            sendData[12] = (byte)(ymd & 0xff);
                            sendData[13] = (byte)((ymd >> 8) & 0xff);
                            sendData[14] = (byte)((hms >> 8) & 0xff);
                            if ((hms & 0xE0) == 0xE0)
                            {
                                sendData[14] = (byte)(sendData[14] + 1);
                            }
                            long cardNO = long.Parse(_CardNo);
                            if (cardNO > 0)
                            {
                                sendData[0] = (byte)(cardNO & 0xff);
                                sendData[1] = (byte)((cardNO >> 8) & 0xff);
                                sendData[2] = (byte)((cardNO >> 16) & 0xff);
                                sendData[3] = (byte)((cardNO >> 24) & 0xff);
                                sendData[4] = (byte)((cardNO >> 32) & 0xff);
                                sendData[5] = (byte)((cardNO >> 40) & 0xff);
                                sendData[6] = (byte)((cardNO >> 48) & 0xff);
                                sendData[7] = (byte)((cardNO >> 56) & 0xff);
                            }
                            var _QrCode = new Sm4Crypto(_QRPassword).Encrypt_ECB_Str(sendData);
                            if (!string.IsNullOrEmpty(_QrCode) && _QrCode.Length > 32)
                            {
                                _QrCode = _QrCode.Substring(0, 32).ToUpper().Replace("-", "");
                            }
                            return new AccessQRCodeOutput()
                            {
                                qrret = 1,
                                msg = "ok",
                                qrcode = _QrCode,
                                endtime = _EndDatetime,
                            };
                        }
                        else
                        {
                            return new AccessQRCodeOutput()
                            {
                                qrret = 0,
                                msg = "非正常户,无法使用",
                                qrcode = "账户禁用",
                                endtime = DateTime.Now,
                            };
                        }                        
                    }
                }
                return new AccessQRCodeOutput()
                {
                    qrret = 0,
                    msg = "获取卡户失败,请重试",
                    qrcode = "",
                    endtime = DateTime.Now.AddMinutes(-100),
                };
            }
            catch (Exception ex)
            {
                return ex.Message;
            }
        }
        long getYMD(int Year, int Month, int Day)
        {
            long ymd;
            ymd = (Year % 100) << 9;
            ymd += (Month << 5);
            ymd += (Day);
            return (long)ymd;
        }
        long getHMS(int Hour, int Minute, int Second)
        {
            long hms = 0;
            hms += ((Second >> 1));
            hms += Minute << (5);
            hms += Hour << (11);
            return hms;
        }
        #endregion

        #region 获取门禁记录
        /// <summary>
		/// 获取门禁记录列表
		/// </summary>
		/// <param name="input">请求参数</param>
		/// <returns></returns>
        [HttpGet("GetRecordList")]
        public async Task<dynamic> GetRecordList([FromQuery] AccessRecordQueryInput input)
        {
            var sidx = input.sidx == null ? "sortCode" : input.sidx;

            var userInfo = await _userManager.GetUserInfo();
            var _EmployeeId = "0";
            if (userInfo != null && userInfo.UserKind == 1 && !string.IsNullOrEmpty(userInfo.EmployeeId))
            {
                _EmployeeId = userInfo.EmployeeId;
            }
            //通行日期
            List<string> queryBillDate = input.passtime != null ? input.passtime.Split(',').ToObeject<List<string>>() : null;
            DateTime? startBilldate = queryBillDate != null ? Convert.ToDateTime(queryBillDate[0]) : Convert.ToDateTime(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));
            DateTime? endBilldate = queryBillDate != null ? Convert.ToDateTime(queryBillDate[0]) : Convert.ToDateTime(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));
            var data = await _db.Queryable<AccessRecordEntity>()
                .Where(a => a.EmployeeId.Equals(_EmployeeId))
                //通行日期
                .WhereIF(queryBillDate != null, a => a.Passtime >= new DateTime(startBilldate.ToDate().Year, startBilldate.ToDate().Month, startBilldate.ToDate().Day, 0, 0, 0))
                .WhereIF(queryBillDate != null, a => a.Passtime <= new DateTime(endBilldate.ToDate().Year, endBilldate.ToDate().Month, endBilldate.ToDate().Day, 23, 59, 59))
                .Select(it => new AccessRecordPageOutput
                {
                    id = it.Id,
                    ctlSn = it.CtlSn,
                    ctlInex = it.CtlInex,
                    cardNo = it.CardNo,
                    passtime = Convert.ToDateTime(it.Passtime).ToString("yyyy-MM-dd HH:mm:dd"),
                    doorNo = it.DoorNo,
                    doorName = it.DoorName,
                    inOrout = it.InOrout,
                    inOroutName = it.InOroutName,
                    passStatus = it.PassStatus,
                    passStatusName = it.PassStatusName,
                    doorAreaName = it.DoorAreaName,
                    ctlposition = it.Ctlposition,
                    sortCode = it.SortCode,
                }).MergeTable().OrderBy(sidx + " desc ").ToPagedListAsync(input.currentPage, input.pageSize);
            return PageResult<AccessRecordPageOutput>.SqlSugarPageResult(data);
        }
        #endregion
    }
}
